/**
 * 
 */
package jnzb.ui;

import java.awt.Font;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.Spring;
import javax.swing.SpringLayout;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;

/**
 * Panel that has all of the data regarding the current NZB file on
 * 
 * @author Rid
 * 
 */
@SuppressWarnings("serial")
public class NZBPanel extends JPanel {

	private static final String NZB_NAME_START_TEXT = "Click the 'Add NZB' button to load NZB file";

	private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

	// Only keep references to things we want to update
	JLabel nzbName = new JLabel(NZB_NAME_START_TEXT);
	// This is something like "5 files (400mb)"
	JLabel sizeSummary = new JLabel(" ");
	JProgressBar nzbProgress = new JProgressBar();
	JLabel completionTime = new JLabel(" ");

	private GregorianCalendar calendar = new GregorianCalendar();

	public NZBPanel() {
		create();

	}

	private void create() {
		// Create the border
		Border etchedBorder = BorderFactory
				.createEtchedBorder(EtchedBorder.LOWERED);
		Border titleBorder = BorderFactory.createTitledBorder(etchedBorder,
				"Current NZB Details");
		this.setBorder(titleBorder);

		this.setLayout(new SpringLayout());

		JLabel nzbNameLabel = new JLabel("NZB filename", JLabel.TRAILING);
		JLabel numFilesLabel = new JLabel("Contains", JLabel.TRAILING);
		JLabel progressLabel = new JLabel("Progress", JLabel.TRAILING);
		JLabel completionTimeLabel = new JLabel("Finish", JLabel.TRAILING);

		// Create a new BOLD version of the current font
		Font boldFont = new Font(super.getFont().getName(), Font.BOLD, super
				.getFont().getSize());
		nzbNameLabel.setFont(boldFont);
		numFilesLabel.setFont(boldFont);
		progressLabel.setFont(boldFont);
		completionTimeLabel.setFont(boldFont);

		this.add(nzbNameLabel);
		this.add(nzbName);
		this.add(numFilesLabel);
		this.add(sizeSummary);
		this.add(progressLabel);
		this.add(nzbProgress);
		this.add(completionTimeLabel);
		this.add(completionTime);

		// Do all spring layout stuff - yes manually, it's easy!
		createLayout(nzbNameLabel, numFilesLabel, progressLabel,
				completionTimeLabel);

		// Set the max height to the preferred height
		SwingUtils.fixMaximumPrefefedHeight(this);

		this.nzbProgress.setMaximum(100);
	}

	/**
	 * Sets the spring constraints
	 * 
	 * @param completionTimeLabel
	 * @param progressLabel
	 * @param sizeLabel
	 * @param numFilesLabel
	 * @param nzbNameLabel
	 */
	private void createLayout(JLabel nzbNameLabel, JLabel numFilesLabel,
			JLabel progressLabel, JLabel completionTimeLabel) {
		SpringLayout layout = (SpringLayout) this.getLayout();

		// Get the constraints for all relevant components
		SpringLayout.Constraints nzbNameCons = layout
				.getConstraints(this.nzbName);
		SpringLayout.Constraints nzbNameLabelCons = layout
				.getConstraints(nzbNameLabel);

		SpringLayout.Constraints numFilesCons = layout
				.getConstraints(this.sizeSummary);
		SpringLayout.Constraints numFilesLabelCons = layout
				.getConstraints(numFilesLabel);

		SpringLayout.Constraints progressCons = layout
				.getConstraints(this.nzbProgress);
		SpringLayout.Constraints progressLabelCons = layout
				.getConstraints(progressLabel);

		SpringLayout.Constraints completionTimeCons = layout
				.getConstraints(this.completionTime);
		SpringLayout.Constraints completionTimeLabelCons = layout
				.getConstraints(completionTimeLabel);

		// Padding value
		Spring padding = Spring.constant(5);

		// Initialised to the initial X position for the first column
		Spring xPos = Spring.constant(5);

		// Create a column for 4 labels where the max width is that of the
		// progress label
		// nzbNameLabelCons.setWidth(progressLabelCons.getWidth());
		numFilesLabelCons.setWidth(nzbNameLabelCons.getWidth());
		completionTimeLabelCons.setWidth(nzbNameLabelCons.getWidth());
		progressLabelCons.setWidth(nzbNameLabelCons.getWidth());

		// For x positioning, as this is the first columns, just set to an
		// initial padding of 5 pixels
		// These are the 4 fields that are on the left making a column
		nzbNameLabelCons.setX(xPos);
		numFilesLabelCons.setX(xPos);
		progressLabelCons.setX(xPos);
		completionTimeLabelCons.setX(xPos);

		// Adjust the X position for the next column - take what we have, add
		// the width of the progress label, plus some padding
		xPos = Spring.sum(xPos, Spring.sum(progressLabelCons.getWidth(),
				padding));

		nzbNameCons.setX(xPos);
		numFilesCons.setX(xPos);
		progressCons.setX(xPos);
		completionTimeCons.setX(xPos);

		// Set the widths so they are all the same as progress bar
		nzbNameCons.setWidth(progressCons.getWidth());
		// Not sure about number files
		numFilesCons.setWidth(progressCons.getWidth());
		completionTimeCons.setWidth(progressCons.getWidth());

		// Set the final xPos so we can set the container width properly
		// Add where we are + width of form field + padding
		xPos = Spring.sum(xPos, Spring.sum(progressCons.getWidth(), padding));

		// This is our starting Y position
		Spring yPos = Spring.constant(5);

		// Set start pos
		nzbNameCons.setY(yPos);
		nzbNameLabelCons.setY(yPos);

		// Set heights to field height
		nzbNameLabelCons.setHeight(nzbNameCons.getHeight());

		// Sum the yPos with where we are + field height + padding
		yPos = Spring.sum(yPos, Spring.sum(nzbNameCons.getHeight(), padding));

		// Next row
		numFilesCons.setY(yPos);
		numFilesLabelCons.setY(yPos);
		numFilesLabelCons.setHeight(numFilesCons.getHeight());

		// Sum the yPos with where we are + field height + padding
		yPos = Spring.sum(yPos, Spring.sum(numFilesCons.getHeight(), padding));

		// Next row
		progressCons.setY(yPos);
		progressLabelCons.setY(yPos);
		progressCons.setHeight(progressLabelCons.getHeight());

		// Sum the yPos with where we are + field height + padding
		yPos = Spring.sum(yPos, Spring.sum(progressLabelCons.getHeight(),
				padding));

		// Last row
		completionTimeCons.setY(yPos);
		completionTimeLabelCons.setY(yPos);
		completionTimeCons.setHeight(completionTimeLabelCons.getHeight());

		// Sum the yPos with where we are + field height + padding
		yPos = Spring.sum(yPos, Spring.sum(completionTimeLabelCons.getHeight(),
				padding));

		// Set the form panel size size.
		SpringLayout.Constraints formPanelConstraints = layout
				.getConstraints(this);

		formPanelConstraints.setHeight(yPos);
		formPanelConstraints.setWidth(xPos);

		// Apply constraints from the north and east to ensure this container
		// sticks to the top and left
		// xPos & yPos now contain the total widths and heights of the contents
		// of the container
		formPanelConstraints.setConstraint(SpringLayout.NORTH, yPos);
		formPanelConstraints.setConstraint(SpringLayout.EAST, xPos);

	}

	/**
	 * Sets the nzb filename in the gui
	 * 
	 * @param filename
	 */
	public void setNZBFilename(final String filename) {
		Runnable r = new Runnable() {
			public void run() {
				nzbName.setText(filename);
				nzbName.setToolTipText(filename);
			}
		};
		SwingUtilities.invokeLater(r);
	}

	public void setContains(final String contains) {
		Runnable r = new Runnable() {
			public void run() {
				sizeSummary.setText(contains);
			}
		};
		SwingUtilities.invokeLater(r);

	}

	/**
	 * Sets the NZB completion time by adding the amount of time left to the
	 * current time
	 * 
	 * @param secondsLeft
	 *            - number of seconds left
	 */
	public void setCompletionTime(int secondsLeft) {

		this.calendar.setTimeInMillis(System.currentTimeMillis());

		this.calendar.add(Calendar.SECOND, secondsLeft);

		final String formattedTime = sdf.format(this.calendar.getTime());

		Runnable r = new Runnable() {
			public void run() {
				completionTime.setText(formattedTime);
			}
		};
		SwingUtilities.invokeLater(r);
	}


	/**
	 * Update the progess bar based on the current bytes downloaded
	 * 
	 * @param percent
	 */
	public void updatePercent(int percent) {

		this.nzbProgress.setValue(percent);
	}


	/**
	 * Resets the fields on the panel to a start state
	 */
	public void resetPanel() {
		Runnable r = new Runnable() {
			public void run() {
				nzbProgress.setValue(0);
				nzbName.setText(NZB_NAME_START_TEXT);
				sizeSummary.setText(" ");
				completionTime.setText(" ");
			}
		};
		SwingUtilities.invokeLater(r);
	}
}
